#include "BaiduASR.h"
#include <QFile>
#include <QUrlQuery>
#include <QNetworkReply>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>

const QString TOKEN_URL = "https://aip.baidubce.com/oauth/2.0/token";
const QString ASR_URL = "https://vop.baidu.com/server_api";

BaiduASR::BaiduASR(const QString& apiKey, const QString& secretKey, QObject *parent)
    : QObject(parent)
    , m_apiKey(apiKey)
    , m_secretKey(secretKey)
    , m_networkManager(new QNetworkAccessManager(this))
{
    requestAndSetAccessToken();
}

BaiduASR::~BaiduASR()
{   
    if (m_networkManager) {
        m_networkManager->deleteLater();
        m_networkManager = nullptr;
    }
}
// 读取文件信息，调用发送函数
void BaiduASR::recognizeFromFile(const QString &filePath) {
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        emit recognitionError("Failed to open audio file");
        return;
    }
    QByteArray audioData = file.readAll();// 读取文件音频信息
    file.close();

    if (m_accessToken.isEmpty()) {
        requestAndSetAccessToken();  // 先获取Token，然后在onAccessTokenReceived中调用sendAudioForRecognition
    }
    sendAudioForRecognition(audioData);
}

void BaiduASR::requestAndSetAccessToken() 
{
    QUrl url(TOKEN_URL);
    QUrlQuery query;
    query.addQueryItem("grant_type", "client_credentials");
    query.addQueryItem("client_id", m_apiKey);
    query.addQueryItem("client_secret", m_secretKey);
    url.setQuery(query);

    QNetworkRequest request(url);
    QNetworkReply* reply = m_networkManager->get(request);
    
    connect(reply, &QNetworkReply::finished, [this, reply]() {
        QByteArray data = reply->readAll();
        reply->deleteLater();

        QJsonDocument doc = QJsonDocument::fromJson(data);
        if (!doc.isObject()) {
            qWarning() << "Token响应格式错误";
            emit recognitionError("Token响应格式错误");
            return;
        }

        QJsonObject obj = doc.object();
        if (obj.contains("error")) {
            QString error = obj["error_description"].toString();
            qWarning() << "获取Token失败:" << error;
            emit recognitionError("获取Token失败: " + error);
            return;
        }

        m_accessToken = obj["access_token"].toString();
        int expiresIn = obj["expires_in"].toInt();
        qDebug() << "成功获取Token,有效期:" << expiresIn << "秒";
        
    });
}
// 发送识别请求
void BaiduASR::sendAudioForRecognition(const QByteArray &audioData)
{
    // 构建ASR请求URL
    QUrl url(ASR_URL);
    QUrlQuery query;
    query.addQueryItem("cuid", generateDeviceId());
    query.addQueryItem("token", m_accessToken);
    query.addQueryItem("format", "pcm");
    query.addQueryItem("rate", "16000");
    query.addQueryItem("channel", "1");
    query.addQueryItem("lan", "zh");  // 中文识别
    url.setQuery(query);

    // 发送POST请求
    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "audio/pcm; rate=16000");
    QNetworkReply* reply = m_networkManager->post(request, audioData);
    reply->setProperty("requestType", "asr");  // 给reply设置属性，而非request
    // 当识别完成，响应接收时，由槽函数onRecognitionResponse处理响应
    connect(reply, &QNetworkReply::finished, [this, reply]() {
        this->onRecognitionResponse(reply); // 确保使用this指针
    });
}

// 处理识别响应
void BaiduASR::onRecognitionResponse(QNetworkReply* reply)
{
    QByteArray data = reply->readAll();
    qDebug() << "ASR原始响应:" << data;
    QJsonDocument doc = QJsonDocument::fromJson(data);
    
    if (doc.isObject()) {
        QJsonObject obj = doc.object();
        if (obj["err_no"].toInt() == 0) {  // 百度API成功标识
            if (obj.contains("result") && obj["result"].isArray()) {
                QJsonArray results = obj["result"].toArray();
                if (!results.isEmpty()) {
                    QString text = results[0].toString();
                    emit recognitionFinished(text);  // 发送识别结果给KingdomWindow
                } else {
                    emit recognitionError("未识别到语音内容");
                }
            }
        } else {
            emit recognitionError(tr("识别失败: %1 (错误码: %2)")
                .arg(obj["err_msg"].toString()).arg(obj["err_no"].toInt()));
        }
    } else {
        emit recognitionError("解析识别响应失败");
    }
}

QString BaiduASR::generateDeviceId() const
{
    // 生成简单的设备唯一标识
    return QCryptographicHash::hash(QSysInfo::machineUniqueId(), QCryptographicHash::Md5).toHex();
}